#Topic type
$topic = 7;

#Part of commandsProper
#       "\@topic", \&createTopic,
#	"\@join", \&joinTopic,
#	"\@leave", \&leaveTopic,

if ( $text =~ /^,(\S+)\s+(.*)$/ ) {
    &topic( $me, "", $1, $2, 0 );
    return;
}

sub createTopic {
    my ( $me, $arg, $arg1, $arg2 ) = @_;
    my ($id);
    if ( !&builderTest($me) ) {
        &tellPlayer( $me, "Sorry, only an authorized builder can do that." );
        return;
    }
    if ( $arg =~ /^\s*$/ ) {
        &tellPlayer( $me,
            "Syntax: \@topic topicname (no commas or spaces allowed)" );
        return;
    }
    if ( length($arg2) ) {
        &tellPlayer( $me,
            "Syntax: \@topic topicname (no commas or spaces allowed)" );
        return;
    }
    if ( $arg =~ /[ ,]/ ) {
        &tellPlayer( $me,
            "Syntax: \@topic topicname no commas or spaces allowed)" );
        return;
    }
    $id = &findTopic( $me, $arg, 1 );
    &tellPlayer( $me,
              "Topic $arg raised. Type ,$arg blah blah... "
            . "to talk about it. You can 'get' the topic if you want "
            . "to carry it off and discuss it elsewhere." );
    $objects[$id]{"lastuse"} = time;
    &topic(
        $me, "",
        $objects[$id]{"name"},
        $objects[$id]{"me"} . "brings up the topic", 1
    );
}

sub findTopic {
    my ( $me, $arg, $exact ) = @_;
    my ($id);

    #1. Exact match for the topic, present in the room already.
    $id = &findContents( $objects[$me]{"location"}, $arg, $topic );
    my ($pat) = quotemeta($arg);
    return $id
        if ( ( $id != $none ) && ( $objects[$id]{"name"} =~ /^$pat$/i ) );

    #2. Exact match for the topic, present in the user's inventory.
    $id = &findContents( $me, $arg, $topic );
    if ( ( $id != $none ) && ( $objects[$id]{"name"} =~ /^$pat$/i ) ) {
        &removeContents( $me, $id );
        $objects[$id]{"location"} = $objects[$me]{"location"};
        &addContents( $objects[$me]{"location"}, $id );
        &tellPlayer( $objects[$id]{"name"} . " dropped." );
        return $id;
    }
    if ( !$exact ) {

        #3. Inexact match for the topic, present in the room already.
        $id = &findContents( $me, $arg, $topic );
        return $id if ( $id != $none );

        #4. Inexact match for the topic, present in the user's inventory.
        $id = &findContents( $me, $arg, $topic );
        if ( $id != $none ) {
            &removeContents( $me, $id );
            $objects[$id]{"location"} = $objects[$me]{"location"};
            &addContents( $objects[$me]{"location"}, $id );
            &tellPlayer( $objects[$id]{"name"} . " dropped." );
            return $id;
        }
    }

    #5. Must be created.
    $id = &addObject( $me, $arg, $topic );
    &addContents( $objects[$me]{"location"}, $id );
    $objects[$id]{"home"} = $me;

    # By default, it is locked to its creator.
    $objects[$id]{"lock"} = "#$me";
    return $id;
}

sub topic {
    my ( $me, $arg, $arg1, $arg2, $emote ) = @_;
    my ($id) = &findContents( $objects[$me]{"location"}, $arg1, $topic );
    if ( $id == $none ) {
        &tellPlayer( $me,
                  "There is no topic here called " . $arg1
                . ". Type \@topic $arg1 to raise a topic." );
        return;
    }
    if ( !&filterTopic( $me, $objects[$id]{"name"} ) ) {
        &tellPlayer( $me,
                  "You are not joined to that topic. "
                . "\@join "
                . $objects[$id]{"name"}
                . " first." );
        return;
    }
    my ($tn) = "<" . $objects[$id]{"name"} . ">";
    if ( !$emote ) {
        my ($output) = "You say$to, \"" . $arg2 . "\" $tn";
        &tellPlayer( $me, $output );
        &tellRoom(
            $objects[$me]{"location"},
            $me,
            $objects[$me]{"name"} . " says, \"" . $arg2 . "\" $tn",
            $objects[$me]{"name"},
            $objects[$id]{"name"}
        );
    }
    else {
        my ($s);
        if ( !( $arg2 =~ /^[,']/ ) ) {
            $s = " ";
        }
        &tellRoom(
            $objects[$me]{"location"},
            "",
            $objects[$me]{"name"} . $s . $arg2 . " $tn",
            $objects[$me]{"name"},
            $objects[$id]{"name"}
        );
    }
    $objects[$id]{"lastuse"} = time;
}

sub filterTopic {
    my ( $me, $topic ) = @_;
    my ($topics) = $objects[$me]{"topics"};
    my ($default);
    return 1 if ( $topic eq "" );
    if ( !exists( $objects[$me]{"topicdefault"} ) ) {
        $default = 1;
    }
    else {
        $default = $objects[$me]{"topicdefault"};
    }
    my (@topics) = split( /,/, $topics );
    for $t (@topics) {
        my ($qm) = quotemeta($topic);
        return !$default if ( $t =~ /^$qm$/i );
    }
    return $default;
}

sub joinTopic {
    my ( $me, $arg, $arg1, $arg2 ) = @_;
    &joinTopicBody( $me, $arg, $arg1, $arg2, 1 );
}

sub leaveTopic {
    my ( $me, $arg, $arg1, $arg2 ) = @_;
    &joinTopicBody( $me, $arg, $arg1, $arg2, 0 );
}

sub joinTopicBody {
    my ( $me, $arg, $arg1, $arg2, $join ) = @_;
    if ( $arg =~ /^all$/i ) {
        $objects[$me]{"topicdefault"} = $join;
        $objects[$me]{"topics"}       = "";
        if ($join) {
            &tellPlayer( $me, "Joining all topics." );
        }
        else {
            &tellPlayer( $me, "Leaving all topics." );
        }
        return;
    }
    my ( $default, %topics );
    if ( !exists( $objects[$me]{"topicdefault"} ) ) {
        $default = 1;
    }
    else {
        $default = $objects[$me]{"topicdefault"};
    }
    my (@topics)  = split( /[ ,]+/, $arg );
    my ($otopics) = $objects[$me]{"topics"};
    my (@otopics) = split( /,/, $otopics );
    $topics{$_} = 1 for (@otopics);
    for $t (@topics) {
        my $id = &findContents( $objects[$me]{"location"}, $t, $topic );
        if ( $id == -1 ) {
            $id = &findContents( $me, $t, $topic );
            if ( $id == -1 ) {
                &tellPlayer( $me, "No topic $t." );
                next;
            }
        }
        my ($tname) = $objects[$id]{"name"};
        if ( $default == $join ) {
            $topics{$tname} = 0;
        }
        else {
            $topics{$tname} = 1;
        }
    }
    @topics = ();
    while ( ( $key, $value ) = each(%topics) ) {
        push @topics, $key if ($value);
    }
    $objects[$me]{"topics"} = join( ',', @topics );
    &tellPlayer( $me, "Topic list updated." );
}

#Part of @stats
#&tellPlayer($me, "Total topics:            " .  int($typeCounts[$topic]));

#Part of sub drop
if ( $objects[$id]{"type"} == $topic ) {
    &createTopic( $me, $arg, $arg1, $arg2 );
    return;
}

#Part of sub dump
# Send stale topics home, if they aren't already home
if ( $objects[$i]{"type"} == $topic ) {
    if ( $objects[$i]{"location"} != $objects[$i]{"home"} ) {
        &sendHome($i) if ( $now - $objects[$i]{"lastuse"} > $topicStaleTime );
    }
}

#part of sub name
if ( $objects[$id]{"type"} == $topic ) {
    if ( $arg2 =~ / ,/ ) {
        &tellPlayer( $me,
            "Commas and spaces are not allowed in topic names." );
        return;
    }
}

#Part of sub describeBody
if ( $objects[$what]{"type"} == $player ) {
    my ($top);
    if (   ( $objects[$what]{"topicdefault"} )
        || ( !exists( $objects[$what] {"topicdefault"} ) ) )
    {
        $top = "Topics: ALL, except: ";
    }
    else {
        $top = "Topics: ";
    }
    my ($tlist) = $objects[$what]{"topics"};
    if ( length($tlist) ) {
        $top .= "$tlist";
    }
    &{$output}( $dest, $top );
}
if ( !$details ) {
    my ($topics);
    foreach $e (@list) {
        $found = 1;
        if ( !$details ) {
            if (   ( $objects[$e]{"type"} == $topic )
                && ( !( $objects[$e]{"flags"} & $flags{"dark"}{"value"} ) ) )
            {
                if ($first) {
                    $first = 0;
                }
                else {
                    $desc .= ", ";
                }
                $desc .= $objects[$e]{"name"};
            }
        }
    }
    if ($found) {
        if ( $objects[$what]{"type"} == $room ) {
            &{$output}( $dest, "Active Topics:" );
        }
        else {
            &{$output}( $dest, "Topics:" );
        }
        &{$output}( $dest, $desc );
    }
}

#From sub tellRoom
# Apply topic filters.
next if ( !&filterTopic( $e, $topic ) );


